#include <iostream>

class Obj {
private:
    int _refCount;

public:
    Obj() {
        _refCount = 1;
        std::cout << "Create Obj\n";
    };

    void sayHello() {
        std::cout << "Hello World!\n";
    }

    void retain() {
        _refCount++;
    }

    void release() {
        _refCount--;
        if (_refCount == 0) {
            delete this;
        }
    }

    int refCount() {
        return _refCount;
    }

    ~Obj() {
        std::cout << "Destroy Obj\n";
    };
};

class AutoRef {
private:
    Obj *_target;

public:
    AutoRef(Obj *obj) {
        obj->retain();
        this->_target = obj;
        // std::cout << "Obj ref count is: " << obj->refCount() << "\n";
    }

    Obj *getTarget() {
        return _target;
    }

    ~AutoRef() {
        this->_target->release();
    }
};


int main() {
    auto obj = new Obj();

    do {
        AutoRef ref(obj);
        ref.getTarget()->sayHello();
    } while (false);

    obj->release();
    return 0;
}
